package www;

/**
 * Creared with IntelliJ IDEA.
 * Description:顺序表的方法
 * User:yxd
 * Date:2022-01-02
 * Time:22:43
 */


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();//底层虽然是数组 但是这个数组没有大小
        list.add("hh");//为什么没有越界  自己的理解：如果 原数组长度等于size那么就让这个新元素grow（扩容）也就是重新创建一个位置
        //老师讲的  当第一次存放数据元素时顺序表被分配大小为10
        //如果ArrayList调用不带参数的构造方法那么顺序表的大小为0，当第一次add时整个顺序表才变为10；当10放慢了开始扩容，以1.5倍的方式进行扩容

        ArrayList<String> list2 = new ArrayList<>(13);//括号内是初始容量
        //如果调用的是给定容量的构造方法，那你的顺序表的大小就是你给定的容量，放满了还是1.5倍进行扩容 的

    }
    public static void main3(String[] args) {
        List<String> list = new ArrayList<>();//也可以换成其他类
        list.add("hhh");//默认放到最后一个位置
        list.add("hhhh");
        list.add("hhhhh");
        list.add(0,"h");//放入指定位置
        System.out.println(list);
        List<String> list2 = new ArrayList<>();
        list2.add("yy");
        list2.add("wx");
        list.addAll(list2);
        System.out.println(list);//放入list2整体
        //list.remove(1);//删除某个位置的
        //System.out.println(list);
        boolean b = list.remove("hhh");//是否有这个元素  有的话删除
        System.out.println(b);
        System.out.println(list);
        System.out.println(list.get(2));//得到下标 的元素
        list.set(2,"w");//更新下标的元素
        System.out.println(list);
        /*list.clear(); 清空
        System.out.println(list);*/
        boolean y = list.contains("w");//是否包含
        System.out.println(y);
        System.out.println(list.indexOf("w"));//所在的下标
        System.out.println(list.lastIndexOf("hhhh"));//最后一个所在的位置
        List<String> sh = list.subList(2,4);//截取2-4位置的元素  左闭右开
        System.out.println(sh);
        sh.set(0,"===");
        System.out.println(sh);
        System.out.println(list);//并不是真正的截取出来了 而是直接这里内存的起始地址赋给了这个
    }
    public static void main2(String[] args) {
        List<String> list = new ArrayList<>();//也可以换成其他类
        list.add("hhh");//默认放到最后一个位置
        list.add("hhhh");
        list.add("hhhhh");
        //打印方法
        System.out.println(list);//1.自己调用toString方法
        //2
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i) + " ");
        }
        System.out.println();
        //3
        for (String s:list) {
            System.out.print(s + " ");
        }
        System.out.println();
        System.out.println("===迭代打印===");
        Iterator<String> it = list.iterator();//iterator迭代器方法  返回值是Iterator
        while(it.hasNext()){//有没有下一个  返回值是true 或false  it从第一个元素的前面开始
            System.out.print(it.next() + " ");
        }
        System.out.println();
        System.out.println("迭代list相关打印");
        //实现了list接口的 都可以使用这个来打印
        ListIterator<String> it2 = list.listIterator();//ListIterator接口实现了Iterator  其功能都有
        // 但还有很多区别 比如这个有add方法remove方法  添加删除的方法  add方法只有这个有  上面的没有
        //remove方法
        /*while(it2.hasNext()){
            //首先需要使用next方法迭代出所有的元素  才能使用remove方法  否则可能会报错  上面的接口也是一样的使用remove方法
            String str = it2.next();
            if(str.equals("hhh")) {
                it2.remove();//不能这样直接删除  删除时可能没有it.next 可能会报异常
                //System.out.print(it2.next() + " ");
            }else{
                System.out.println(str + " ");
            }
        }*/
        //add方法
        while(it2.hasNext()){

            String str = it2.next();
            if(str.equals("hhh")) {
                it2.add("yxd");//会添加到这个位置的后面 此时it指向这个元素
                //如果直接使用list来add会报错  ArrayList不是线程安全的  适用于单线程 一边遍历一遍添加就会报错
                // CopyOnWriteArrayList是线程安全的 是一边写以便拷贝的使用这个list类就不会出错 适用于多线程
            }else{
                System.out.print(str + " ");
            }
        }
        System.out.println("=======");
        System.out.println(list);
    }
}
